package com.gticket.orderservice.service.impl;

import com.gticket.orderservice.dto.TimeOrder;
import com.gticket.orderservice.mapper.ActualSeatMapper;
import com.gticket.orderservice.mapper.OrderItemMapper;
import com.gticket.orderservice.mapper.OrderMapper;
import com.gticket.orderservice.pojo.ActualSeat;
import com.gticket.orderservice.pojo.OrderItems;
import com.gticket.orderservice.pojo.Orders;
import com.gticket.orderservice.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;

/**
 * @Author: 伴你时光尽头
 * @Date: 2019/11/18 16:13
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private ActualSeatMapper actualSeatMapper;


    /**
     * 查询整个影院所有的订单信息
     *
     * @param orders 包含影院的数据库特有字段信息的order对象
     * @return
     */

    @Override
    public List<Orders> getAll(Orders orders) {
        System.out.println("正在查询");
        return orderMapper.getAll(orders);
    }

    /**
     * 添加订单 并返回订单编号
     *
     * @param orders
     * @return
     */
    @Override
    public Integer addOrder(Orders orders) {
        orderMapper.addOrder(orders);
        return orderMapper.selectOrder_idByOrderNum(orders);
    }

    /**
     * 改变订单状态为  2  已失效
     *
     * @param orders
     */
    @Override
    public void updateState(Orders orders) {
        orderMapper.updateState(orders);
    }

    /**
     * 查询订单状态  返回对应的额状态值
     *
     * @param orders
     * @return
     */
    @Override
    public int getState(Orders orders) {
        return orderMapper.getState(orders);
    }


    /**
     * 根据订单编号id查询对应orders表中所有信息
     * 根据order_id在orderitems表中查询对应订单的订单项List
     *
     * @param orders orders对象中封装信息为数据库前缀名和订单编号id
     * @return
     */
    @Override
    public Orders getOrderById(Orders orders) {
        Orders order = orderMapper.getOrderById(orders);//获取订单信息
        order.setDatabasename(orders.getDatabasename());
        order.setCinema_name(orderMapper.getCinema_nameByCinema_id(order));//获取影院名
        List<OrderItems> items = orderItemMapper.getItemsById(orders);//获取订单项
        BigDecimal totalprice = new BigDecimal("0");

        for (OrderItems item : items) {
            item.setMovie_name(orderItemMapper.getMovie_nameByFs_id(item));//通过fs_id获取电影名
            BigDecimal movie_price = orderItemMapper.getMovie_priceByFs_id(item);
            item.setMovie_price(movie_price);
            /*         ***********************/
            System.out.println(item);
            orderItemMapper.setMovie_price(item);
            item.setStart_time(orderItemMapper.getStart_timeByFs_id(item));//通过fs_id  查询影片开始时间start_time
            item.setCh_name(orderItemMapper.getCH_nameByFs_id(item));
            totalprice = totalprice.add(movie_price);
        }
//        System.out.println(items);
        order.setTotalprice(totalprice);//设置总价
        orderMapper.setTotalPrice(order);
        order.setOrderItemss(items);//封装订单项到order中
        return order;
    }

    /**
     * 根据User_id查询对应orders表中所有信息
     * 根据order_id在orderitems表中查询对应订单的订单项List
     *
     * @param orders orders对象中封装信息为数据库前缀名和订单编号id
     * @return
     */

    @Override
    public List<Orders> getOrderByUser_id(Orders orders) {
        List<Orders> orderss = orderMapper.getOrderByUser_id(orders);//
        System.out.println("........................................................");
        System.out.println(orderss);
        for (Orders order : orderss) {
            order.setDatabasename(orders.getDatabasename());
            order.setCinema_name(orderMapper.getCinema_nameByCinema_id(order));//获取影院名
            System.out.println(order);
            List<OrderItems> items = orderItemMapper.getItemsById(order);//获取订单项
            BigDecimal totalprice = new BigDecimal("0");

            for (OrderItems item : items) {
                item.setDatabasename(orders.getDatabasename());
                item.setMovie_name(orderItemMapper.getMovie_nameByFs_id(item));//通过fs_id获取电影名
                BigDecimal movie_price = orderItemMapper.getMovie_priceByFs_id(item);
                item.setMovie_price(movie_price);

                item.setStart_time(orderItemMapper.getFs_dateByFs_id(item) + " " + orderItemMapper.getStart_timeByFs_id(item));//通过fs_id  查询影片开始时间start_time
                item.setCh_name(orderItemMapper.getCH_nameByFs_id(item));
                totalprice = totalprice.add(movie_price);
            }
            System.out.println("订单项");
            System.out.println(items);
            order.setTotalprice(totalprice);//设置总价
            order.setOrderItemss(items);//封装订单项到order中
        }
        System.out.println("订单集合");
        System.out.println(orderss);
        return orderss;
    }


    /**
     * 根据传入的时间段查询订单
     * <p>
     * String转化为Timestamp:
     * String tsStr = "2011-05-09 11:49:45";
     * try {
     * ts = Timestamp.valueOf(tsStr);
     * System.out.println(ts);
     * } catch (Exception e) {
     * e.printStackTrace();
     * }
     * 注：String的类型必须形如： yyyy-mm-dd hh:mm:ss[.f...] 这样的格式，中括号表示可选，否则报错！！！
     *
     * @param orders 传入时间段   开始时间start_time  和结束时间lastTime
     * @return
     */
    @Override
    public List<Orders> getOrderBYCreate_time(Orders orders) {
        //将字符串转换为timestamp
        Timestamp create_time = Timestamp.valueOf(orders.getCreate_time());
        //将字符串转换为timestamp
        Timestamp lastTime = Timestamp.valueOf(orders.getLastTime());
        return orderMapper.getOrderBYCreate_time(new TimeOrder(orders.getDatabasename(), create_time, lastTime));
    }

    /**
     * 根据订单编号修改订单状态为已取消  5
     *
     * @param orders
     */
    @Override
    public void changeOrderStateByOrder_id(Orders orders) {
        orderMapper.changeOrderStateByOrder_id(orders);
    }


    /**
     * 通过order_num和databasename查询对应的数据行
     *
     * @param orders
     * @return
     */
    @Override
    public Orders getOrdersByOrder_num(Orders orders) {
//        System.out.println(orders);
        Orders order = orderMapper.getOrdersByOrder_num(orders);
//        System.out.println(order+"/////");
        order.setDatabasename(orders.getDatabasename());
        order.setCinema_name(orderMapper.getCinema_nameByCinema_id(order));//获取影院名
//        System.out.println(order+"***************************************");
        List<OrderItems> items = orderItemMapper.getItemsById(order);//获取订单项
//        System.out.println(items+"***************************************");
        BigDecimal totalprice = new BigDecimal("0");

        for (OrderItems item : items) {
            item.setMovie_name(orderItemMapper.getMovie_nameByFs_id(item));//通过fs_id获取电影名
            BigDecimal movie_price = orderItemMapper.getMovie_priceByFs_id(item);
            item.setMovie_price(movie_price);
            /*         ***********************/
            System.out.println(item);
            orderItemMapper.setMovie_price(item);
            item.setStart_time(orderItemMapper.getStart_timeByFs_id(item));//通过fs_id  查询影片开始时间start_time
            item.setCh_name(orderItemMapper.getCH_nameByFs_id(item));
            totalprice = totalprice.add(movie_price);
        }
//        System.out.println(items);
        order.setTotalprice(totalprice);//设置总价
        System.out.println(order+"***************************************");
        orderMapper.setTotalPrice(order);
        order.setOrderItemss(items);//封装订单项到order中
//        System.out.println(orders1)
        return order;
    }


    /**
     * 通过order_num和databasename在对应的order中存入交易号
     *
     * @param orders
     */
    @Override
    public void setPay_num(Orders orders) {
        orderMapper.setPay_num(orders);
    }

    /**
     * 改变订单状态为  1  已支付
     *
     * @param orders
     */
    @Override
    public void updateStateToAlreadyPay(Orders orders) {
        orderMapper.updateStateToAlreadyPay(orders);
    }

    /**
     * 改变订单状态状态为  5 已取消s
     *
     * @param orders
     */
    @Override
    public void updateStateToAlreadyCancel(Orders orders) {
        orderMapper.updateStateToAlreadyCancel(orders);
        orderMapper.deleteTicketnum(orders);
    }

    /**
     * 通过order_num和databasename在对应的order中存入    取票码
     *
     * @param orders
     */
    @Override
    public void setTicketnum(Orders orders) {
        orderMapper.setTicketnum(orders);
    }


    /**
     * 获取订单的订单项  电影的开场时间
     *
     * @param orders
     * @return
     */
    @Override
    public String getMovieStartTime(Orders orders) {
        //获取日期（格式为2019-12-31）
        String day = orderItemMapper.getFs_dateByFs_id(orderItemMapper.getItemsById(orders).get(0));
        //获取时分（格式为11:11）
        String time = orderItemMapper.getStart_timeByFs_id(orderItemMapper.getItemsById(orders).get(0));

        return day + " " + time;
    }


    /**
     * 用于已购票未使用 但是电影已经播放完成   此时自动修改电影订单为已完成或已使用状态
     *
     * @param orderItems
     */
    @Override
    public void updateStateComplete(OrderItems orderItems) {
        orderMapper.updateStateComplete(orderItems);
    }

    /**
     * 根据取票码取票时   将对应的订单状态更改为已取票
     *
     * @param orders
     */
    @Override
    public void updataStateToAlreadyTake(Orders orders) {
        orderMapper.updataStateToAlreadyTake(orders);
    }

    @Override
    public Orders getOrderByTicketnum(Orders orders) {
        orders = orderMapper.getOrdersByTicketnum(orders);
        orders.setCinema_name(orderMapper.getCinema_nameByCinema_id(orders));
        List<OrderItems> items = orderItemMapper.getItemsById(orders);
        for (OrderItems item : items) {
            item.setCh_name(orderItemMapper.getCH_nameByFs_id(item));
            item.setMovie_name(orderItemMapper.getMovie_nameByFs_id(item));
            item.setStart_time(orderItemMapper.getStart_timeByFs_id(item));
        }
        orders.setOrderItemss(items);
        items = null;

        return orders;
    }

    /**
     * 将当前user  当前电影场次  之前未支付的订单直接取消
     *
     * @param orders
     */
    @Override
    public void cancelInvalidOrder(Orders orders) throws Exception {
        orders.setOrderItemss(orderItemMapper.getItemsById(orders));
        //获取当前订单的fs_id
        Integer fs_id = orders.getOrderItemss().get(0).getFs_id();
        //通过当前订单的 user和fs_id 查询所有相同的订单
        //获取该user的所有订单
        List<Orders> orders1 = orderMapper.getOrderByUser_id(orders);
        for (Orders orders2: orders1) {
            orders2.setDatabasename(orders.getDatabasename());
            orders2.setOrderItemss(orderItemMapper.getItemsById(orders2));
            System.out.println(orders2);
            //排除当前订单
           if(orders2.getOrder_id()!=orders.getOrder_id()){
               //如果其他订单的fs_id和当前订单的fs_id相同则将   orders2的订单状态设置为已取消 并将订单中的座位释放
               //同时订单状态需要满足  orderstate为0未支付
               if(fs_id==orders2.getOrderItemss().get(0).getFs_id()&&orders2.getOrder_state()==0){
                   //orders2的订单状态设置为已取消
                   orderMapper.changeOrderStateByOrder_id(orders2);
                   //订单中的座位释放
                   //释放座位
                   Integer as_id = null;
                   List<OrderItems> items = orders2.getOrderItemss();
                   for (OrderItems item : items) {
                       item.setDatabasename(orders.getDatabasename());
                       log.error("座位释放row：" + item.getRow() + "col:" + item.getCol());
                       //根据订单项  将座位表修改
                       ActualSeat actualSeat = actualSeatMapper.selectActualSeatByAs_id(item);
                       as_id = actualSeat.getAs_id();
                       //通过反射获取当前订单中座位的行
                       Class<?> ActualSeat = Class.forName("com.gticket.orderservice.pojo.ActualSeat");
                       Object obj = ActualSeat.newInstance();
                       Method method = ActualSeat.getDeclaredMethod("getRow_" + item.getRow(), null);
                       String temp = (String) method.invoke(actualSeat);//指定行
                       StringBuffer stemp = new StringBuffer(temp);
                       stemp.replace(item.getCol(), item.getCol()+1, "1");
                       //反射设置对应行
                       actualSeat = new ActualSeat();
                       actualSeat.setDatabasename(item.getDatabasename());
                       Method method1 = ActualSeat.getDeclaredMethod("setRow_" + item.getRow(), String.class);
                       method1.invoke(actualSeat,stemp.toString());
                       actualSeat.setAs_id(as_id);
                       actualSeatMapper.changeRow(actualSeat);
                       actualSeat = null;
                   }
               }
           }
        }
    }

}
